Could not load the default credentials.
google-auth-library が認証情報を見つけられていない or timeout している
GCP 環境上で動作させる際に、認証情報を渡さなくても実行環境上で探してくれるのだが、失敗したり timeout したりしてエラーになった場合に起きる
回避策
Service Account のキーを発行して一緒にデプロイし GOOGLE_APPLICATION_CREDENTIALS に渡す
process.env.GOOGLE_APPLICATION_CREDENTIALS = './my-secret.json';
鍵の管理、サービスアカウントの role の管理、デプロイフローに影響するのであまりやりたくない......
アプリケーション起動時に待ってあげるとうまくいかないか?
→ getApplicationDefaultAsync() 空打ちしても安定しない
コードリーディング
getApplicationDefaultAsync
$HOME/.config/gcloud/application_default_credentials.json に置かれているの知らなかった
isGCE = await this._checkIsGCE();
this.checkIsGCE = await gcpMetadata.isAvailable();
この結果はキャッシュされる
code:google-auth-library/src/auth/googleauth.ts
async _checkIsGCE() {
if (this.checkIsGCE === undefined) {
this.checkIsGCE = await gcpMetadata.isAvailable();
}
return this.checkIsGCE;
}
失敗したらそれが使われ続ける
! コールドスタートしてキャッシュなくて取り直す → そこから失敗し続けるパターン isAvailable()
code:gcp-metadata/src/index.ts
cachedIsAvailableResponse = metadataAccessor(
'instance',
undefined,
detectGCPAvailableRetries(),
true
);
metadataAccessor()
http リクエスト投げている
${BASE_URL}/${type}${property},
BASE_URL: http://169.254.169.254/computeMetadata/v1
type: instance
property: ''
これが timeoutしている
fastFail=true のとき fastFailMetadataRequest()
BASE_URL と SECONDARY_URL
SECONDARY_URL: http://metadata.google.internal.
http://169.254.169.254/computeMetadata/v1
http://metadata.google.internal./computeMetadata/v1
return Promise.race([r1, r2]);
race で並列に叩いて早い方を使う!! おもしろい
compute client、GCP 実行環境上で動く
GCE metadata サーバー
Cloud Shell 内からだと metadata.google.internal が見える
code:shell
pokutuna@cloudshell:~ (pokutuna-playground)$ curl http://metadata.google.internal/computeMetadata/v1/instance/name
devshell-vm-23a348f3-7923-4f31-8fa0-3b12a333847b
Compute client getApplicationDefaultAsync で呼んだ時 serviceAccountEmail: 'default' 以外あるのか?
ぱっと眺めた感じはなさそう
gcloud deploy functions --service-account=... だと default がそれになるのか? そういう気もあまりしないけど
どうやって token とっているの
fetchIdToken
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
デフォルトサービスアカウントの AccessToken が返ってる?
default を任意のメールアドレスにできる?
接続ユーザなり Cloud Shell 立ち上げたユーザなりで制限されていそう
ユーザのリクエストそのまま Proxy するようなの
グローバルスコープで GCP クライアントライブラリを new しない
ほんとにこれでいいのか??